// Hash.h: interface for the Hash class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_HASH_H__A6C73351_6CE0_45BB_870B_A6D229A7E748__INCLUDED_)
#define AFX_HASH_H__A6C73351_6CE0_45BB_870B_A6D229A7E748__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ManagerTemplate.h"
#include "UeObjectId.h"
#include "PersistentObject.h"

namespace PDMS
{
	namespace PDMSDBIF
	{
		class PersisterFacadeImp;
	}
	namespace PDMSFrame
	{
		class UeDbObject;
		
		class DllExport Hash
		{
			friend class UeDbObject;
			friend class PDMSPerObjManager;
			friend class TestHash;
			friend class PDMSDBIF::PersisterFacadeImp;

		private:

		public:
			typedef ManagerTemplate< UeObjectId, UeDbObject > HashContainer;
			typedef MapEx< StdString, UeObjectId > NameToIDMap;
			
		public:
			class DllExport iterator
			{
			public:
				virtual ~iterator(){}
				
			public:
				virtual void Begin() = 0;
				virtual BOOL End() = 0;
				virtual void Next() = 0;
				virtual UESoft::ErrorStatus GetObject( UeDbObject*& pTree,
					UeDb::OpenModel om = UeDb::eForWrite ) = 0;
			};
			
			typedef UeSmartPtr< iterator > IteratorPtr;
			
		private:
		public:
			Hash();
			virtual ~Hash();
			
		public:
			UESoft::ErrorStatus GetObject( const UeObjectId& id , UeDbObject*& pTree,
				UeDb::OpenModel om = UeDb::eForWrite );
			
			IteratorPtr GetObject( const StdString& id, BOOL atBeginning = TRUE,
								   BOOL skipDeleted = TRUE  );

			INT Size() {
				return m_Container.GetElementCount();
			}

			IteratorPtr Iterator(BOOL atBeginning = TRUE, BOOL skipDeleted = TRUE );

			PDMSPerObjManager* Database() {
				return m_pDB;
			}

		protected:
			UESoft::ErrorStatus Add( UeDbObject* pTree );
			void RemoveAll();

			void Database( PDMSPerObjManager* pDB ) {
				ASSERT( pDB );
				m_pDB = pDB;
			}

			void NameChange( const UeObjectId& id,
				const StdString& strOldName, const StdString& strNewName );
		private:
			PDMSPerObjManager* m_pDB;
			HashContainer m_Container;
			NameToIDMap m_NameToIDMap;
		};
		
		class HashIterator : public Hash::iterator
		{
			friend class Hash;
		private:
			HashIterator( Hash::HashContainer::Iterator* pIt,
				BOOL atBeginning, BOOL skipDeleted ){
				ASSERT( pIt );
				m_pIt = pIt;
				if ( !atBeginning )
				{
					while ( !m_pIt->End() )
					{
						m_pIt->Next();
					}
				}
				m_skipDeleted = skipDeleted;
			}
			
		public:
			virtual ~HashIterator() {
				if ( m_pIt != NULL )
					delete m_pIt;
			}
		public:
			virtual void Begin();
			
			virtual BOOL End() {
				return m_pIt->End();
			}
			
			virtual void Next();
			
			virtual UESoft::ErrorStatus GetObject( UeDbObject*& pTree,
				UeDb::OpenModel om = UeDb::eForWrite );
			
		private:
			Hash::HashContainer::Iterator* m_pIt;
			BOOL m_skipDeleted;
		};
		
		class SameIDIterator : public Hash::iterator
		{
			friend class Hash;
		private:
			SameIDIterator( Hash::NameToIDMap::Iterator* pIt, Hash* pHash ,
				BOOL atBeginning, BOOL skipDeleted ){
				ASSERT( pIt );
				ASSERT( pHash );
				m_pIt = pIt;
				m_pHash = pHash;
				if ( !atBeginning )
				{
					while ( !m_pIt->End() )
					{
						m_pIt->Next();
					}
				}
				m_skipDeleted = skipDeleted;
			}
			
		public:
			virtual ~SameIDIterator() {
				if ( m_pIt != NULL )
					delete m_pIt;
			}
		public:
			virtual void Begin();
			
			virtual BOOL End() {
				return m_pIt->End();
			}
			
			virtual void Next();
			
			virtual UESoft::ErrorStatus GetObject( UeDbObject*& pTree,
				UeDb::OpenModel om = UeDb::eForWrite );
			
		private:
			Hash::NameToIDMap::Iterator* m_pIt;
			Hash* m_pHash;
			BOOL m_skipDeleted;
		};

	}
}

#define GetTree GetObject

#endif // !defined(AFX_HASH_H__A6C73351_6CE0_45BB_870B_A6D229A7E748__INCLUDED_)
